﻿using MathNet.Numerics.IntegralTransforms;
using System;
using System.Collections.Generic;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using UtilZ.Dotnet.Ex.Base;
using UtilZ.Dotnet.Ex.DataStruct;
using UtilZ.Dotnet.Ex.FourierTransform;
using UtilZ.Dotnet.Ex.Model;

namespace ConAppCore.Test
{
    unsafe internal class TestFlexibleArray
    {
        public static void Test()
        {

            //FlexibleArray<double> subcalres = new FlexibleArray<double>();
            //subcalres.CheckSetLength(5);
            //subcalres[0] = 12;
            //subcalres[1] = 25;
            //subcalres[2] = 8;
            //subcalres[3] = 86;
            //subcalres[4] = 0;
            //Span<double> xx = subcalres.GetSpan(4);

            int[] arr3222 = new int[0];
            Span<int> ints = new Span<int>(arr3222);
            ints.Clear();




            using var doublePtr1 = new UnmanagedMemoryPointer<double>();
            SpanZ<double> span0 = doublePtr1.GetSpanZ(10);
            LocalSpanZ<double> lspan0 = span0.ToLocalSpanZ();

            Parallel.For(0, span0.Length, (i) =>
            {
                lspan0[i] = Thread.CurrentThread.ManagedThreadId * 100 + i;
            });


            int[] arr32 = new int[5];
            for (int i = 0; i < arr32.Length; i++)
            {
                arr32[i] = i;
            }
            int* pt1 = (int*)Unsafe.AsPointer<int>(ref arr32[0]);

            ref int _reference = ref MemoryMarshal.GetArrayDataReference(arr32);
            int* pt2 = (int*)Unsafe.AsPointer<int>(ref _reference);


            for (int i = 0; i < arr32.Length; i++)
            {
                Console.WriteLine($"pt1:{pt1[i]}        pt2:{pt2[i]}");
            }

            //ref int _reference = ref MemoryMarshal.GetArrayDataReference(arr32);
            //ref int _reference2 = ref Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(arr32), (nint)(uint)3); /* force zero-extension */
            Memory<int> memory = MemoryMarshal.CreateFromPinnedArray<int>(arr32, 0, arr32.Length);


            int index = 2;
            //ref Unsafe.Add<int>(ref _reference, (nint)(uint) index );/* force zero-extension */
            int value = Unsafe.AddByteOffset<int>(ref _reference, (nint)(index * sizeof(int)));
            //ref Unsafe.As<byte,int>(ref Unsafe.As<Array.RawData>(arr32).Data);


            SpanZ<double> span = doublePtr1.GetSpanZ(5);
            span[0] = 12;
            span[1] = 25;
            span[2] = 8;
            span[3] = 86;
            span[4] = 10;
            var arr1 = new ValueTypeFlexibleArray<double>(FlexibleArrayMode.Referenced);
            arr1.Reference(span);

            //using var arr2 = new ValueTypeFlexibleArray<double>(FlexibleArrayMode.Independent);
            //arr2.CheckSetLength(5);
            //arr2[0] = 20;
            //arr2[1] = 30;
            //arr2[2] = 0;
            //arr2[3] = 0;
            //arr2[4] = 0;

            //arr2.CheckSetLength(10);
            //for (int i = 0; i < arr2.Length; i++)
            //{
            //    arr2[i] = i;
            //}

            //TestFlexibleArray1();
            //TestValueTypeFlexibleArray();
            //TestIQValueTypeFlexibleArray();

            //using var doublePtr1 = new UnmanagedMemoryPointer<double>();
            //Span<double> span = doublePtr1.GetSpan(5);
            //span[0] = 12;
            //span[1] = 25;
            //span[2] = 8;
            //span[3] = 86;
            //span[4] = 10;
            //span.Clear();


            //EnumerableEx.Order(span);
            //EnumerableEx.OrderDescending(span);



            TestFFF();
        }


        private static void TestFFF()
        {
            using var pointer = new UnmanagedMemoryPointer<Complex>(800);
            var span = pointer.GetSpanZ();
            FileEx.ReadIQ(@"D:\Projects\212\Release\Complex_800_93.dat", 0, TypeCode.Int16, span);

            FourierEx.Forward(span, FourierOptions.Matlab);
        }

        private static void TestIQValueTypeFlexibleArray()
        {
            using var arr = new IQValueTypeFlexibleArray<int>(10, 5);
            arr.SetIData(0, 10);
            arr.SetIData(1, 25);
            arr.SetIData(2, 86);
            arr.SetIData(3, 45);
            arr.SetIData(4, 32);

            arr.SetQData(0, 78);
            arr.SetQData(1, 98);
            arr.SetQData(2, 16);
            arr.SetQData(3, 64);
            arr.SetQData(4, 32);

            arr.Check(20);

            var arr2 = arr.Slice(1, 2);
            //arr2.Check(20);
        }

        private static void TestFlexibleArray1()
        {
            var arr = new FlexibleArray<int>(5, 5);
            arr[0] = 5;
            arr[1] = 15;
            arr[2] = 65;
            arr[3] = 20;
            arr[4] = 30;

            var x1 = arr.First();
            var x2 = arr.Last();

            //for (int i = 0; i < arr.Length; i++)
            //{
            //    Console.WriteLine(arr[i]);
            //}
            foreach (var item in arr)
            {
                Console.WriteLine(item);
            }

            //arr.Order();
            //arr.OrderDescending();

            string str = arr.ToString(',');

            var arr2 = new FlexibleArray<int>(5, 5);
            arr.CopyTo(arr2);

            Span<int> span = arr.GetSpan();
            arr.Fill(100);

            var arr3 = arr.ToArray();
            arr.Clear();

            var list = arr.ToList();

        }

        private static void TestValueTypeFlexibleArray()
        {
            //using var arr = new ValueTypeFlexibleArray<sbyte>(5, 5);
            //using var arr = new ValueTypeFlexibleArray<byte>(5, 5);
            //using var arr = new ValueTypeFlexibleArray<short>(5, 5);
            //using var arr = new ValueTypeFlexibleArray<ushort>(5, 5);
            //using var arr = new ValueTypeFlexibleArray<int>(5, 5);
            //using var arr = new ValueTypeFlexibleArray<uint>(5, 5);
            //using var arr = new ValueTypeFlexibleArray<long>(5, 5);
            //using var arr = new ValueTypeFlexibleArray<ulong>(5, 5);
            //using var arr = new ValueTypeFlexibleArray<float>(5, 5);
            using var arr = new ValueTypeFlexibleArray<double>(5, 5);
            arr[0] = 5;
            arr[1] = 15;
            arr[2] = 65;
            arr[3] = 20;
            arr[4] = 30;

            var x1 = arr.First();
            var x2 = arr.Last();

            //for (int i = 0; i < arr.Length; i++)
            //{
            //    Console.WriteLine(arr[i]);
            //}
            foreach (var item in arr)
            {
                Console.WriteLine(item);
            }

            //arr.Order();
            //arr.OrderDescending();

            var sli = arr.Slice(2, 2);

            string str = arr.ToString(',');

            //using var arr2 = new ValueTypeFlexibleArray<sbyte>(5, 5);
            //using var arr2 = new ValueTypeFlexibleArray<byte>(5, 5);
            //using var arr2 = new ValueTypeFlexibleArray<short>(5, 5);
            //using var arr2 = new ValueTypeFlexibleArray<ushort>(5, 5);
            //using var arr2 = new ValueTypeFlexibleArray<int>(5, 5);
            //using var arr2 = new ValueTypeFlexibleArray<uint>(5, 5);
            //using var arr2 = new ValueTypeFlexibleArray<long>(5, 5);
            //using var arr2 = new ValueTypeFlexibleArray<ulong>(5, 5);
            //using var arr2 = new ValueTypeFlexibleArray<float>(5, 5);
            using var arr2 = new ValueTypeFlexibleArray<double>(5, 5);
            arr.CopyTo(arr2);

            var span = arr.GetSpan();
            arr.Fill(100);

            var arr3 = arr.ToArray();

            var list = arr.ToList();


        }
    }
}
